package drds.plus.sql_process.abstract_syntax_tree.expression.item.function;

import drds.plus.common.jdbc.Parameters;
import drds.plus.sql_process.abstract_syntax_tree.IExecutePlanVisitor;
import drds.plus.sql_process.abstract_syntax_tree.ObjectCreateFactory;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;


public class LogicalOperationFilterImpl extends FunctionImpl<LogicalOperationFilter> implements LogicalOperationFilter {
    @Setter
    @Getter
    protected Operation operation;

    public LogicalOperationFilterImpl() {
        argList = new ArrayList<Filter>();
    }

    public void setOperation(Operation operation) {
        this.operation = operation;
        this.functionName = operation.getOperationString();

    }

    public Operation getOperation() {
        return operation;
    }

    public List<Filter> getFilterList() {
        return argList;
    }

    public void setFilterList(List<Filter> filterList) {
        this.setArgList(filterList);

    }

    public Filter getLeft() {
        if (this.argList.isEmpty()) {
            return null;
        }

        return (Filter) this.argList.get(0);
    }

    public Filter getRight() {
        if (this.argList.size() < 2) {
            return null;
        }

        return (Filter) argList.get(1);
    }

    public void setLeft(Filter left) {
        if (this.argList.isEmpty()) {
            this.argList.add(left);
        } else {
            this.argList.set(0, left);
        }

    }

    public void setRight(Filter Right) {
        if (this.argList.isEmpty()) {
            this.argList.add(null);
            this.argList.add(Right);
        } else if (this.argList.size() == 1) {
            this.argList.add(Right);
        } else {
            this.argList.set(1, Right);

        }

    }

    public void addFilter(Filter filter) {
        this.argList.add(filter);

    }

    public LogicalOperationFilter assignment(Parameters parameters) {
        LogicalOperationFilter logicalOperationFilter = super.assignment(parameters);
        logicalOperationFilter.setOperation(this.getOperation());
        return logicalOperationFilter;
    }


    public LogicalOperationFilter copy() {
        LogicalOperationFilter logicalOperationFilter = ObjectCreateFactory.createLogicalOperationFilter();
        super.copy(logicalOperationFilter);
        logicalOperationFilter.setOperation(this.getOperation());
        return logicalOperationFilter;
    }

    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((operation == null) ? 0 : operation.hashCode());
        result = prime * result + ((argList == null) ? 0 : argList.hashCode());
        return result;
    }

    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (!(obj instanceof LogicalOperationFilter)) {
            return false;
        }
        LogicalOperationFilter other = (LogicalOperationFilter) obj;
        if (getOperation() != other.getOperation()) {
            return false;

        }
        if (getFilterList() == null) {
            return other.getFilterList() == null;
        } else
            return getFilterList().equals(other.getFilterList());
    }

    public void accept(IExecutePlanVisitor executePlanVisitor) {
        executePlanVisitor.visit(this);
    }

}
